perm filename OUT[CLS,LSP] blob
sn#854511 filedate 1988-03-13 generic text, type T, neo UTF8
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/147L
1) 1) We specify only subclass relationships, and no direct subclasses.
1) This allows implementations to insert implementation dependent classes
**** File 2) MOPC.TEX[CLS,LSP]/1P/147L
2) 1. We specify only subclass relationships, and no direct subclasses.
2) This allows implementations to insert implementation dependent classes
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/151L
1) 2) We specify as disjoint the metaclasses that support built-in classes,
1) structure classes and standard classes. These metaclasses are
**** File 2) MOPC.TEX[CLS,LSP]/1P/151L
2) 2. We specify as disjoint the metaclasses that support built-in classes,
2) structure classes and standard classes. These metaclasses are
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/157L
1) 3) We provide classes in the kernel to support default behavior of
1) instances of standard-class and structure-class. These are the
1) classes {\it standard-object} and {\it structure-object} respectively.
1) 4) In the kernel, we define classes {\it class}, {\it slot-description},
1) {\it method}, {\it generic-function}, and {\it method-combination}. These
**** File 2) MOPC.TEX[CLS,LSP]/1P/157L
2) 3. We provide classes in the kernel to support default behavior of
2) instances of standard-class and structure-class. These are the
2) classes {\it standard-object} and {\it structure-object} respectively.
2) 4. In the kernel, we define classes {\it class}, {\it slot-description},
2) {\it method}, {\it generic-function}, and {\it method-combination}. These
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/172L
1) 5) We do not specify slots in any class in the kernel, although
1) implementations are free to use them. We define reader generic
**** File 2) MOPC.TEX[CLS,LSP]/1P/172L
2) 5. We do not specify slots in any class in the kernel, although
2) implementations are free to use them. We define reader generic
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/384L
1) is used to check the compatibility of each slot-description-object. If
1) valid-slot-description-p returns nil, an error is signalled
1)
**** File 2) MOPC.TEX[CLS,LSP]/1P/384L
2) is used to check the compatibility of each slot-description-object.
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) If valid-slot-description-p returns nil, an error is signalled
2)
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/432L
1) \Defmeth {class-default-direct-superclasses} {(class funcallable-standard-class) supplied-superclasses)}
1) If {\bf supplied-superclasses} is nil, then this method returns a list
**** File 2) MOPC.TEX[CLS,LSP]/1P/433L
2) \Defmeth {class-default-direct-superclasses} {(class funcallable-standard-class) supplied-superclasses}
2) If {\bf supplied-superclasses} is nil, then this method returns a list
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/454L
1) (or supplied-superclasses
1) (list (symbol-class 'loops-object))))
1) \endscreen!
**** File 2) MOPC.TEX[CLS,LSP]/1P/455L
2) (or supplied-superclasses
2) (list (symbol-class 'loops-object))))
2) \endscreen!
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/506L
1) \endSubSection%{Initializing standard-class}
**** File 2) MOPC.TEX[CLS,LSP]/1P/507L
2)
2) \beginsubsubsection{valid-slot-option-p}
2) The purpose of this generic function is to allow checking of slot
2) description options without having to construct the slot descriptions
2) themselves. The argument to this method is the class-prototype
2) of the class of slot-description object that is to be constructed for
2) this class. Since all of the options are to be iniitialization
2) arguments for initialize-instance, the effective code for the standard
2) method can be:
2) \screen!
2) (defmethod valid-slot-option-p ((slotd standard-slot-description) option-keyword)
2) (member option-keyword
2) (method-applicable-keywords
2) #'initialize-instance
2) (list slotd))))
2)
2) \endscreen!
2) \endsubsubsection%{valid-slot-option-p}
2) \endSubSection%{Initializing standard-class}
***************
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1192L
1) This is a lambda-list of the form described for defgeneric. The lambda-list
1) argument must be provided or an error is signalled.
1) {\bf :argument-precedence-order}
**** File 2) MOPC.TEX[CLS,LSP]/1P/1218L
2) This is a lambda-list of the form described for defgeneric.
2) {\bf :argument-precedence-order}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1330L
1) The methods on standard-generic-function and standard-method both
1) call {\bf generic-function-changed} when they actually make a change.
1) The standard method on add-method calls add-method-on-specializer.
**** File 2) MOPC.TEX[CLS,LSP]/1P/1355L
2) The standard method on add-method calls add-method-on-specializer.
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1471L
1) ((object standard-object) &rest reinit-args)
1) ;; signals an error on bad arguments
**** File 2) MOPC.TEX[CLS,LSP]/1P/1494L
2) ((object standard-object) &rest reinit-args)
2) ;; signals an error on bad arguments
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1476L
1) ((object standard-object) &rest reinit-args)
1) ;; reuse initialization methods
1) (apply #'initialize-instance
1) object
1) :allow-other-keys 't
1) reinit-args))
1) (defmethod reinitialize-instance :after
1) ((object standard-object) &rest reinit-args)
1) ;; updates dependents
1) (apply #'update-dependents object reinit-args))
1) \endscreen!
**** File 2) MOPC.TEX[CLS,LSP]/1P/1499L
2) ((object standard-object) &rest reinit-args)
2) ;; reuse initialization methods
2) (apply #'initialize-instance
2) object
2) :allow-other-keys 't
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) reinit-args))
2) (defmethod reinitialize-instance :after
2) ((object standard-object) &rest reinit-args)
2) ;; updates dependents
2) (apply #'update-dependents object reinit-args))
2) \endscreen!
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1510L
1) ((object standard-object) reinit-args)
1) (let* ((arglist (list object))
1) (acceptable-args
1) (union
**** File 2) MOPC.TEX[CLS,LSP]/1P/1533L
2) ((object standard-object) reinit-args)
2) (let* ((arglist (list object))
2) (acceptable-args
2) (union
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1517L
1) (zl:loop (key in reinit-args by cddr)
1) (unless (member key acceptable-args) (error ...))))
1) \endscreen!
**** File 2) MOPC.TEX[CLS,LSP]/1P/1540L
2) (do* ((tail reinit-args (cddr tail))
2) (key (car tail) (car tail)))
2) ((null tail))
2) (unless (member key acceptable-args :test #'eq)
2) (error ...)))))
2) \endscreen!
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1537L
1) The standard method on update-dependents maps through all the dependents of the object, calling update-dependent. Although
1) the standard method makes use of the database, for special cases
1) update-dependents may have its own way of updating the dependents without
1) mapping through a list of registered dependents
1)
**** File 2) MOPC.TEX[CLS,LSP]/1P/1562L
2) The method on update-dependents specialized to standard-object maps through all the dependents of the object, calling update-dependent. Although
2) the standard method does guarantee to do the mapping, for special cases
2) update-dependents may have its own way of updating the dependents without
2) mapping through a list of registered dependents.
2) The style recommended for use of this facility is not to make update-dependent be recursive, and have all dependnts, whether
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) direct or indirect, be added to the set of dependents.
2)
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1546L
1) object
1) #'(lambda (changed-object dependent update-args)
1) (apply #'update-dependent changed-object dependent update-args))
1) update-args))
1) \endscreen!
1) \endsubsubsection%{update-dependents}
1)
**** File 2) MOPC.TEX[CLS,LSP]/1P/1574L
2) object
2) #'(lambda (changed-object dependent update-args)
2) (apply #'update-dependent changed-object dependent update-args))
2) update-args))
2) \endscreen!
2) \endsubsubsection%{update-dependents}
2)
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1562L
1) (apply \#'map-fn object dependent other-args)
1) The key difference between methods on this generic function are how
1) dependents are found.
1) \endsubsubsection%{map-dependents}
**** File 2) MOPC.TEX[CLS,LSP]/1P/1590L
2) \screen!
2) (apply #'map-fn object dependent other-args)
2) \endscreen!
2) \endsubsubsection%{map-dependents}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1574L
1) \endsubsubsection%{add-dependents}
**** File 2) MOPC.TEX[CLS,LSP]/1P/1602L
2) In some cases, at the time of adding a dependent,
2) the user may want to store additional information
2) about the form of the dependence. Rather than providing an additional
2) argument to add-dpendent, the user is expected to define
2) a special object that captures the dependent, and the additional
2) information. This is in the spirit of representing compound
2) structures as objects rather than as lists. It also allows the type
2) of the dependent object to be used to select the method.
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) \endsubsubsection%{add-dependents}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1583L
1) \beginsubsubsection{update-dependent - no default method}
1) \Defgen {update-dependent} {object \&rest update-args}
**** File 2) MOPC.TEX[CLS,LSP]/1P/1620L
2) \beginsubsubsection{update-dependent}
2) \Defgen {update-dependent} {object \&rest update-args}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1605L
1) when a defclass form is reevaluated. All subclasses that need
1) to be informed when a class has changed must register themselves as
1) dependents using add-dependent. A specialized method on update-dependent
1) is used to propogate all necesary changes to the subclass.
1)
1) The only specialized method for {\bf reinitialize-instance}
1) for standard-class is:
1) \screen!
1) The keywords accepted by this method are just those of
1) initialize-instance for standard-class.
1) (defmethod reinitialize-instance ((class standard-class) &rest reinit-args)
1) (let ((old-direct-super-classes (class-direct-superclasses class))
1) (call-next-method)
1) (let ((new-direct-super-classes (class-direct-superclasses class))
1) (dolist (c (set-difference
1) old-direct-super-classes
1) new-direct-super-classes))
1) ;;remove obsolete direct subclass links
1) ;;initialize-instance adds the links for new subclasses
1) (remove-direct-subclass c class))
1) )))
1) \endscreen!
**** File 2) MOPC.TEX[CLS,LSP]/1P/1642L
2) For example, this happens when a defclass form is reevaluated.
2) All subclasses need
2) to be informed when a class has changed must register themselves as
2) dependents using add-dependent. A specialized method on update-dependent
2) is used to propagate all necessary changes to the subclass.
2)
2) The only specialized method for {\bf reinitialize-instance}
2) for standard-class is a primary method that helps in updating
2) of the direct-subclasses.
2) The keywords accepted by this method are just those of
2) initialize-instance for standard-class.
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) \screen!
2) (defmethod reinitialize-instance ((class standard-class) &rest reinit-args)
2) (let ((old-direct-super-classes (class-direct-superclasses class)))
2) (call-next-method)
2) (let ((new-direct-super-classes (class-direct-superclasses class)))
2) (dolist (c (set-difference old-direct-super-classes
2) new-direct-super-classes))
2) ;; remove obsolete direct subclass links
2) ;; initialize-instance adds the links for new subclasses
2) (remove-direct-subclass c class)))))
2) \endscreen!
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1638L
1) {(class standard-class) (subclass standard-class))}
1) This generic function adds subclass to the value
**** File 2) MOPC.TEX[CLS,LSP]/1P/1674L
2) {(class standard-class) (subclass standard-class)}
2) This generic function adds subclass to the value
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1649L
1) This generic function removes the subclass from the value
**** File 2) MOPC.TEX[CLS,LSP]/1P/1685L
2) \Defmeth {remove-direct-subclass}
2) {(class standard-class) (subclass standard-class)}
2) This generic function removes the subclass from the value
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1658L
1) This method maintains classes when changes have occurred in the
1) class lattice above them. It also called by finalize-inheritance
1) to cause inherited information to be collected in the class.
1) The system-supplied method may conspire with
1) methods for {\bf make-instance}, {\bf default-initargs}, {\bf
1) check-initargs}, {\bf allocate-instance}, and {\bf initialize-instance}
1) to speed up object creation by precomputing information. This
1) optimization is implementation dependent, but the {\bf update-dependent}
1) mechanism that makes such optimizations possible is standardized.
1) Users with special optimization needs can write methods for
**** File 2) MOPC.TEX[CLS,LSP]/1P/1697L
2) The purpose of this method is to collect inherited information in the
2) class. This includes the class-slots and class-precedence-list.
2) When changes occur in the class lattice at or above any dependent
2) class, {\bf update-dependent} causes this collected information
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) to be updated. {\bf update-dependent} is also called by
2) finalize-inheritance to ensure that the class contains the
2) information necessary for instance creation.
2) The system-supplied method may conspire with methods for
2) {\bf make-instance}, {\bf default-initargs}, {\bf check-initargs},
2) {\bf allocate-instance}, and {\bf initialize-instance}
2) to speed up object creation by precomputing and caching additional
2) information. This optimization is implementation dependent,
2) but the {\bf update-dependent} mechanism that makes such optimizations
2) possible is standardized.
2) Users with special optimization needs can write methods for
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1677L
1) (defmethod update-dependent :around ((reinitialized-class standard-class)
1) (dependent standard-class)
1) &rest other-args)
1) ;; Implementation specific code to account for the fact that
1) ;; the access keys for this class may change. This is required to
1) ;; cause the optimization of standard-instance-access to
1) ;; continue to work.
1) ;; This may call make-instance-obsolete.
1) )))
1) \endscreen!
**** File 2) MOPC.TEX[CLS,LSP]/1P/1723L
2) (defmethod update-dependent :around ((reinitialized-class standard-class)
2) (dependent standard-class)
2) &rest other-args)
2) ;; Implementation specific code to account for the fact that
2) ;; the access keys for this class may change. This is required to
2) ;; cause the optimization of standard-instance-access to
2) ;; continue to work.
2) ;; This may call make-instances-obsolete.
2) )
2) \endscreen!
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1692L
1) It registers this class as a dependent of every class on its
1) class-precedence-list.
1) It computes the list of all slots by calling collect-slot-descriptions.
1) This value is stored as the value for the reader class-slots.
1) When reinitialized-class = dependent, it goes through the slots
1) and creates readers and writers as specified.
**** File 2) MOPC.TEX[CLS,LSP]/1P/1739L
2) This method registers {\it dependent} as a dependent of every class on its
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) class-precedence-list.
2) It computes the list of all slots by calling collect-slot-descriptions.
2) This value is stored as the value for the reader class-slots.
2) When reinitialized-class = dependent, it goes through class-direct-slots
2) and creates readers and writers as specified.
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1707L
1) (dependent standard-class)
1) &key direct-superclasses
1) direct-slots
1) direct-options)
1) ;; When we are called,there are two cases. In one case
1) ;; this method has been called from finalize-inheritance
1) ;; In this case, the old cpl, slots, and generated
1) ;; readers and writers are nil. We can check this case by
1) ;; using the predicate class-finalized-p.
1) ;; In the general case, the dependent is finalized. We
1) ;; have to do whatever updating is required to keep us finalized.
1) ;; This includes:
1) ;; - recomputing our class-precedence-list
1) ;; go through the old and new cpls, calling remove-dependent
1) ;; and add-dependent to update our dependents.
1) ;; - recomputing our slots, this may change the value that
1) ;; class-access-keys will be returning.
1) ;; - go through the old and new slots adding and removing
1) ;; automatically generated reader and writer methods as
1) ;; required.
1) ;; - update the effect of class-options
1) )
1) \endscreen!
1) Note that this update-dependent method is not recursive.
1) Indirect dependency of classes is not supported.
1) All classes that depend in any way on
1) a possible class must register themselves directly as dependents.
1) \endsubsubsection%{update-dependent for standard-class}
1) \beginsubsubsection{finalize-inheritance}
1) The purpose of this generic function is to inform a class that it should
1) ensure that all inherited information is now collected in the class.
1) This generic-function is expected to be called only once. For
**** File 2) MOPC.TEX[CLS,LSP]/1P/1755L
2) (dependent standard-class)
2) &key direct-superclasses
2) direct-slots
2) direct-options)
2) ;; When we are called,there are two cases. In one case
2) ;; this method has been called from finalize-inheritance
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) ;; In this case, the old cpl, slots, and generated
2) ;; readers and writers are nil. We can check this case by
2) ;; using the predicate class-finalized-p.
2) ;; In the general case, the dependent is finalized. We
2) ;; have to do whatever updating is required to keep us finalized.
2) ;; This includes:
2) ;; - recomputing our class-precedence-list
2) ;; go through the old and new cpls, calling remove-dependent
2) ;; and add-dependent to update our dependents.
2) ;; - recomputing our slots, this may change the value that
2) ;; class-access-keys will be returning.
2) ;; - go through the old and new slots adding and removing
2) ;; automatically generated reader and writer methods as
2) ;; required.
2) ;; - update the effect of class-options
2) )
2) \endscreen!
2) Note that as indicated in the style note above, this update-dependent
2) method for standard-class is not recursive. Indirect dependency of classes
2) is not supported. All subclasses that depend on a class must register themselves directly as dependents.
2) \endsubsubsection%{update-dependent for standard-class}
2) \beginsubsubsection{finalize-inheritance}
2) \Defmeth {finalize-inheritance} {(class standard-class)}
2) The purpose of this generic function is to
2) ensure that all inherited information is now collected in {\it class}.
2) This generic-function is expected to be called only once. For
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1757L
1) Slot description objects are immutable after creation. An error is signalled
1) if an attempt is made to reinitialize a slot-description object.
1) \endsubsubsection%{reinitialize-instance for slot-description}
1) \beginsubsubsection{reinitialize-instance for methods}
1) An error is signalled if an attempt is made to reinitialize a
**** File 2) MOPC.TEX[CLS,LSP]/1P/1806L
2) \Defmeth {reinitialize-instance} {(class standard-slot-description)}
2) Slot description objects are intended to be immutable after creation.
2) An error is signalled if an attempt is made to reinitialize a
2) slot-description object.
2) \endsubsubsection%{reinitialize-instance for slot-description}
2) \beginsubsubsection{reinitialize-instance for methods}
2) \Defmeth {reinitialize-instance} {(meth standard-method)}
2) An error is signalled if an attempt is made to reinitialize a
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1770L
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) \endsubsubsection%{reinitialize-instance for methods}
1) \beginsubsubsection{reinitialize-instance for method-combination objects}
1) Method combination objects are immutable after creation.
1) An error is signalled if an attempt is made to reinitialize a
**** File 2) MOPC.TEX[CLS,LSP]/1P/1824L
2) \Defmeth {reinitialize-instance} {(meth standard-accessor-method)}
2) An error is signalled if an attempt is made to reinitialize a
2) method while it is on a generic function. Otherwise, any of the
2) arguments to initialize-instance will override the
2) currrent value in the method.
2) \endsubsubsection%{reinitialize-instance for methods}
2) \beginsubsubsection{reinitialize-instance for method-combination objects}
2) \Defmeth {reinitialize-instance} {(meth method-combination)}
2) Method combination objects are intended to be immutable after creation.
2) An error is signalled if an attempt is made to reinitialize a
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1788L
1) :documentation :method-class :method-combination :methods}
1) This method checks the new value of lambda-list, then removes previous
1) initial-methods and does a call-next-method.
1) Any of the arguments that are not provided, except methods default to their
1) previous value. If there are any changes, it calls generic-function-changed.
1) {\bf :lambda-list} If the lambda-list is not congruent to the
**** File 2) MOPC.TEX[CLS,LSP]/1P/1850L
2) :documentation :method-class :method-combination :initial-methods}
2) This method then removes the set of initial-methods from the generic
2) function. Then, if there are any methods on the generic function,
2) it checks to see if the newly provided lambda-list is congruent with the
2) previous lambda-list. If not, it signals an error.
2) It then does (call-next-method).
2) {\bf :lambda-list} If the lambda-list is not congruent to the
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1803L
1) \beginsubsubsection{generic-function-changed}
1) \Defmeth {generic-function-changed} {(g-fn standard-generic-function)
1) \&key :argument-precedence-order-changed :declare-changed
1) :method-combination-changed :method-added :method-removed}
1) The standard method on generic-function-changed takes arguments
1) which let it know what has changed that may affect the code for the
1) generic-function. Except for methods-added and methods-removed,
1) these are all flags.
1) This generic function is called by reinitialize-instance for
1) standard-generic-function, and by add-method and remove-method.
1)
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) \endsubsubsection%{generic-function-changed}
1) \endSection%{Reinitialization and Updating Dependents}
**** File 2) MOPC.TEX[CLS,LSP]/1P/1868L
2) \endSection%{Reinitialization and Updating Dependents}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1852L
1) \&key :name :super-names :slot-specifications :direct-options :environment}
1) The :super-names argument can be a list of either symbols (class names)
**** File 2) MOPC.TEX[CLS,LSP]/1P/1900L
2) \&key :name :superclass-names :slot-specifications :direct-options :environment}
2) The :super-names argument can be a list of either symbols (class names)
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1875L
1) (mapcar
1) #'(lambda(s)
1) (cond((typep s 'class) s)
1) ((or (null s)(not (symbolp s))) (error ...))
1) ((cboundp s) (symbol-class s))
1) ;; create a standard-class named s with no direct-superclasses
1) ;; this supports the forward-referencing of standard-class
1) ;; this uninitialized class can be reinitialized
1) ;; but will cause an error if any of its subclasses has its
1) ;; inheritance finalized
1) (t (add-named-class
1) (class-prototype (symbol-class 'standard-class))
1) :name s)))))
1) direct-superclasses)
1) \endscreen!
1) This normalized list is used as the value for direct-superclasses.
1) The next step performed by this method is to determine the class object
**** File 2) MOPC.TEX[CLS,LSP]/1P/1923L
2) (mapcar #'(lambda(s)
2) (cond ((typep s 'class) s)
2) ((or (null s) (not (symbolp s)))
2) (error ...))
2) ((cboundp s)
2) (symbol-class s))
2) ;; create a standard-class named s with no
2) ;; direct-superclasses this supports the
2) ;; forward-referencing of standard-class this
2) ;; uninitialized class can be reinitialized
2) ;; but will cause an error if any of its
2) ;; subclasses has its inheritance finalized
2) (t (add-named-class
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) (class-prototype (symbol-class 'standard-class))
2) :name s))))
2) direct-superclasses)
2) \endscreen!
2) This normalized list is used as the value for direct-superclasses.
2) The slot-specifications are parsed to turn them into slot description
2) objects. The class-prototype is used to determine the class
2) of the slot-description objects. For details, see the slot parsing protocol.
2) The next step performed by this method is to determine the class object
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1899L
1) The slot-specifications are parsed to turn them into slot description
1) objects. The class-prototype is used to determine the form
1) of the slot-description objects. For details, see the slot parsing protocol.
1) If there was no existing class with the given name, make-instance is called
**** File 2) MOPC.TEX[CLS,LSP]/1P/1953L
2) If there was no existing class with the given name, make-instance is called
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1911L
1) \endsubsubsection%{add-named-class}
1) \beginsubsubsection{class-for-redefinition}
1) \Defgen {class-for-redefinition} {prototype-instance old-class}
1) class-for-redefinition is called by the standard method on
**** File 2) MOPC.TEX[CLS,LSP]/1P/1960L
2) Some model code for this function is:
2) \screen!
2) (defmethod add-named-class ((prototype standard-class)
2) &rest keys
2) &key name
2) superclass-names
2) slot-specifications
2) direct-options
2) environment)
2) (let* ((direct-superclasses (mapcar ..))
2) (slot-descriptions (mapcar ..))
2) (new-class ()))
2) (remf keys :name)
2) (remf keys :superclass-names)
2) (remf keys :slot-specifications)
2) (if (cboundp name)
2) (progn
2) (setq new-class
2) (apply #'class-for-redefinition
2) (symbol-class name)
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) prototype
2) :direct-superclasses direct-supers
2) :slot-descriptions slot-specifications
2) keys))
2) (apply #'reinitialize-instance
2) new-class
2) :direct-supers direct-supers
2) :slot-specifications slot-specifications
2) keys))
2) (progn
2) (setq new-class
2) (apply #'make-instance
2) prototype
2) :direct-supers direct-supers
2) :slot-specifications slot-specifications
2) keys))
2) (setf (class-name new-class name))
2) (setf (symbol-class name environment) new-class)))
2) new-class))
2) \endscreen!
2) \endsubsubsection%{add-named-class}
2) \beginsubsubsection{class-for-redefinition}
2) \Defgen {class-for-redefinition} {prototype-instance old-class \&key :direct-superclasses :direct-slots :direct-options :environment}
2) class-for-redefinition is called by the standard method on
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1922L
1) the class object used is the old class object since standard class
1) supports the notion of updating old instances to reflect new definitions
1) of the class. Other metaclasses might not support this notion, they
1) might want new class definitions to use a new class object or even
1) signal an error if an attempt is made to redefine a class.
**** File 2) MOPC.TEX[CLS,LSP]/1P/2014L
2) the class object returned is the old class object since standard class
2) supports the notion of updating old instances to reflect new definitions
2) of the class. Other metaclasses might not support this notion; they
2) might want new class definitions to use a new class object, or perhaps to
2) signal an error if an attempt is made to redefine a class.
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/1990L
1) The expansion of a defgeneric is approximately
1) \screen!
1) (let((g-fn
1) (ensure-generic-function <name>
1) :method-combination (method-combination-object <meth-comb-arg>)
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) ...))) ;; include other arguments directly from defgeneric
1) (reinitialize-instance g-fn
1) :methods (list (defmethod ...) (defmethod ...))))
1) \endscreen!
**** File 2) MOPC.TEX[CLS,LSP]/1P/2082L
2) Following is one model of the expansion of defgenric. {\it We have to check that this really does what we want. It is probably still wrong}
2) \screen!
2) (let ((g-fn
2) (ensure-generic-function <name>
2) :method-combination (method-combination-object <meth-comb-arg>)
2) ;; include other arguments directly from defgeneric
2) ...)))
2) (reinitialize-instance g-fn
2) :initial-methods
2) (list (make-instance (generic-function-method-class g-fn)
2) :lambda-list ...
2) :function #'(method-lambda ..)
2) ..)
2) ..)))
2) \endscreen!
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2041L
1) method-lambda-form)
1) for example,
1) \screen!
1) (defmethod (setf foo) :before ((x c1) y &rest z) (do-foo ...))
1) would expand into
1) (add-named-method '(setf foo) '(:before)
1) '((x c1) y &rest z) (method-lambda (x y &rest z) (do-foo ...)))
1) \endscreen!
1)
1) \beginsubsubsection{add-named-method}
1) The purpose of {\bf add-named-method} is to a a method to the a named generic function. Some model code for for this function is:
1) \screen!
1) (defun add-named-method
1) (name qualifiers method-lambda-list method-lambda-fn)
1) (let* ((g-fn (ensure-generic-function name))
1) (method (make-instance (generic-function-method-class g-fn)
1) :method-function method-lambda-fn
1) :qualifiers qualifiers
1) :lambda-list (strip-lambda-list method-lambda-list))))
1) (add-method g-fn method)
1) method))
1) \endscreen!
1) \endsubsubsection%{add-named-method}
**** File 2) MOPC.TEX[CLS,LSP]/1P/2139L
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) method-specializers method-lambda-form)
2) For example,
2) \screen!
2) (defmethod (setf foo) :before ((x c1) (y (eql *foo*)) z &optional (r 1))
2) (do-foo ...))
2) would expand into
2) (add-named-method
2) '(setf foo)
2) '(:before)
2) '(x y z &optional (r 1))
2) (list (symbol-class 'c1 environment) (list 'eql *foo*) (symbol-class t))
2) #'(method-lambda (x y &optional (r 1)) (do-foo ...)))
2) \endscreen!
2) The method-lambda-list and the specializers must be computed
2) byt the macro expansion function in order for the forms in the eql
2) specializers to be evaluated in the correct lexical environment.
2) The expansion uses two auxilliary functions,
2) {\bf extract-lambda-list} and {\bf extract-specializers} to extract
2) from the specialized lambda-list for the method the pieces needed for
2) constructing a method.
2) These auxiliary functions may be useful for users and are described below.
2)
2) \beginsubsubsection{add-named-method}
2) The purpose of {\bf add-named-method} is to add a method to the named generic
2) function.
2) Some model code for add-named-method function is:
2) \screen!
2) (defun add-named-method
2) (name qualifiers lambda-list specializers function)
2) (let* ((gfn (ensure-generic-function name))
2) (method (make-instance (generic-function-method-class g-fn)
2) :lambda-list lambda-list
2) :specializers specializers
2) :qualifiers qualifiers
2) :method-function function)))
2) (add-method gfn method)
2) method))
2) \endscreen!
2) \beginsubsubsection{extract-lambda-list}
2) \Defun {extract-lambda-list} {specialized-lambda-list \&optional generic-function-lambda-list-p}
2) The purpose of this function is to construct a lambda list from a
2) specialized lambda-list of the type specified for methods (See chapter 1).
2) The optional argument {\it generic-function-lambda-list-p} specifies whether
2) th resulting lambda-list is to be used in the definition of a generic
2) function or a method. For a method, the resulting lambda-list is identical
2) to the input lambda-list except that specializers on the required arguments
2) are stripped off. If {\it generic-function-lambda-list-p} is t, then
2) the default values for optional arguments are also stripped off, and
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) if there is an \&key or \&rest, the resulting lambda-list has an \&rest argument.
2) Thus we have:
2) \screen!
2) (extract-lambda-list
2) '((x x-class)(y (eql 1)) &optional (z 2) &key w)
2) nil)
2) ==> (x y &optional (z 2) &key w)
2) -------------
2) (extract-lambda-list
2) '((x x-class)(y (eql 1)) &optional (z 2) &key w)
2) t)
2) ==> (x y &optional z &rest rest-args)
2) \endscreen!
2) These specifications are designed to conform to the minimal specifications of
2) lambda-list congruence given in Chapter 1.
2) \endsubsubsection%{extract-lambda-list}
2) \endsubsubsection%{extract-specializers}
2) \beginsubsubsection{extract-specializers}
2) \Defun {extract-specializers} {specialized-lambda-list}
2) The purpose of this function is to construct from a specialized lambda-list
2) a form that will evaluate to the list of specializers for this method.
2) This list has the same length as the number of required arguments
2) for the specialized-lambda-list.
2) {\it Question: How does the environment get passed in here?}
2) \endsubsubsection%{add-named-method}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2100L
1) (defclass short-form-method-combination
1) (method-combination)
1) ((name :initarg name :reader method-combination-name)
1) (order :initarg order)
1) (documentation :initarg documentation :reader documentation)
1) (operator :initarg operator)
1) (identity-with-one-argument :initarg identity-with-one-argument)))
1) (defmethod method-combination-options ((mc short-form-method-combination))
**** File 2) MOPC.TEX[CLS,LSP]/1P/2269L
2) (defclass short-form-method-combination (method-combination)
2) ((name :initarg name :reader method-combination-name)
2) (order :initarg order)
2) (documentation :initarg documentation :reader documentation)
2) (operator :initarg operator)
2) (identity-with-one-argument :initarg identity-with-one-argument)))
2) (defmethod method-combination-options ((mc short-form-method-combination))
***************
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2112L
1) methods
1) (mc short-form-method-combination))
1) (let ((primary-methods (remove (list (slot-value mc 'name))
**** File 2) MOPC.TEX[CLS,LSP]/1P/2280L
2) (mc short-form-method-combination)
2) methods)
2) (let ((primary-methods (remove (list (slot-value mc 'name))
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2153L
1) :most-specific-last))
1) (make-instance 'short-form-method-combination
1) 'name ',name
**** File 2) MOPC.TEX[CLS,LSP]/1P/2321L
2) :most-specific-last))
2) (make-instance 'short-form-method-combination
2) 'name ',name
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2203L
1) methods
1) (mc standard-method-combination-with-or))
1) (let ((or-methods (remove '(:or) methods :key #'method-qualifiers
**** File 2) MOPC.TEX[CLS,LSP]/1P/2371L
2) (mc standard-method-combination-with-or)
2) methods)
2) (let ((or-methods (remove '(:or) methods :key #'method-qualifiers
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2232L
1) Standard classes store two distinct lists of slots. The first is the
1) list of slots defined in the class proper. The second is the total list
1) of slots the class has. This includes inherited and locally defined
1) slots. Both of these are available as lists of slot description objects.
1) As part of defining a class, the normalized slot specifications passed
1) to add-named-class must be converted to a list of slot description
1) objects. The normalization is simply to ensure that the slot-name is
1) preceded in the list describing the slot by the keyword :name.
1) This conversion to slot description objects is done using the slot
1) parsing protocol.
1) The slot parsing protocol is quite simple. It only contains only two
1) steps: a call to the generic function slot-description-class and a call
1) to make-instance.
1) Normalized slot-specifications are always parsed with respect to the
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) class they specify a slot for. This allows the class the slot
1) description is being produced for to control the class of the slot
1) description object itself. This slot-description-class generic function
1) is called with the class and the normalized slot specification to
1) determine the class of slot description which should be produced for the
1) class.
1) Once the appropriate class for the slot description has been determined,
1) the actual parsing is achieved by applying make-instance to the class and
1) the normalized slot specification.
1) This means that the legal set of slot option names for a given class of
**** File 2) MOPC.TEX[CLS,LSP]/1P/2400L
2) In converting a slot specification of the kind specified for defclass
2) into a slot description object, the parsing goes through three steps. The
2) first normalizes the specification into a keyword list of the kind acceptable
2) to initialize-instance. It converts a slot specification that is just the
2) symbol {\it x} to {\it (:name x)}, and pushes :name on the front of all other
2) slot specifications.
2) In the second step, the class of the slot-description object is
2) determined by a call to the generic function {\bf slot-description-class}.
2) Finally, an instance of that class is created using make-instance, and the
2) normalized slot-specification as initialization arguments.
2) \screen!
2) (apply #'make-instance
2) (slot-description-class
2) (class-prototype specified-metaclass)
2) normalized-slot-specification)
2) normalized-slot-specification)
2) \endscreen!
2) This means that the legal set of slot option names for a given class of
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2269L
1) The slot-description-class generic function..
1) \Defmeth {slot-description-class} {(class standard-class)
**** File 2) MOPC.TEX[CLS,LSP]/1P/2430L
2) \Defgen {slot-description-class} {containing-class normalized-slot-specification}
2) The purpose of the generic function {\bf slot-description-class} is to
2) return the class to be used in the construction of a slot-description object
2) for a {\it containing-class}. The reason normalized-slot-specification is
2) passed to this generic function is to allow specializations that
2) can use the specification itself to determine the class.
2) \Defmeth {slot-description-class} {(class standard-class)
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2282L
1) \beginSection{compute-class-precedence-list}
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) This generic function computes the class precedence list of a class as described in Chapter 1. The value is a list of class objects in order.
**** File 2) MOPC.TEX[CLS,LSP]/1P/2449L
2) \beginSection{Computing Inherited Information}
2) \beginsubsubsection{compute-class-precedence-list}
2) This generic function computes the class precedence list of a class as described in Chapter 1. The value is a list of class objects in order.
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2290L
1) runs across a class for which
1) (class-initialized-p class)=nil
1) an error is signalled.
1) \endSection%{compute-class-precedence-list}
1) \beginSection{The Slot Inheritance Protocol}
1) The total set of slots for any given class is computed by combining the
1) locally defined slots for the class and all of its superclasses. For
1) standard classes, this combination proceeds according to the rules
1) described in chapter 1. This combination is implemented by the
1) slot inheritance protocol.
1) The computation of the set of slots and their descriptions are
**** File 2) MOPC.TEX[CLS,LSP]/1P/2459L
2) runs across a standard-class for which
2) (class-initialized-p class)=nil
2) an error is signalled.
2) \endsubsubsection%{compute-class-precedence-list}
2) \beginSubSection{The Slot Inheritance Protocol}
2) The value of class-slots for any standard-class is computed by combining the
2) class-direct-slots for the class and all of its superclasses. This combination
2) is specified by the rules described in chapter 1.
2) The computation of the set of slots and their descriptions are
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2322L
1) It sorts all the slots found into sets with the same name, ordered by
1) precedence according to the class precedence list. It then calls
1) compute-effective-slotd to combine multiple definitions of a single slot.
1) \endsubsubsection%{collect-slot-descriptions}
**** File 2) MOPC.TEX[CLS,LSP]/1P/2488L
2) It sorts all the slots found into lists of slot-descriptions that
2) have the same name. Each list is a mapping from the class-precedence-list,
2) and has either a slot-description object or nil if none was defined
2) at that class in the class-precedence-list. It calls
2) compute-effective-slot-description with this list to create the
2) new effective slot-description object.
2) For example, we mgiht have:
2) \screen!
2) (defclass foo ()
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) ((a :initform 1)
2) (b :initform 2)))
2) (defclass bar (foo)
2) ((c :initform 3)))
2) (defclass baz (bar)
2) ((a :initform 4)))
2) There will be the following arguments to calls to
2) compute-effective-slot-description:
2) (#<slotd a :initform 4> NIL #<slotd a :initform 1>)
2) (#<slotd c :initform 3> NIL NIL)
2) (NIL #<slotd b :initform 2> NIL)
2) But they might not be in that order.
2) \endscreen!
2) \endsubsubsection%{collect-slot-descriptions}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2334L
1) of slot options that is described in Chapter 1. It returns a
1) slot-description object with a description computed from all the
**** File 2) MOPC.TEX[CLS,LSP]/1P/2528L
2) of slot options that is described in Chapter 1. It returns a new
2) slot-description object with a description computed from all the
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2362L
1) (when (slot-boundp super-slot 'type)
1) (unless (subtypep slotd-type (slot-value super-slot 'type))
**** File 2) MOPC.TEX[CLS,LSP]/1P/2556L
2) (when (and super-slot
2) (slot-boundp super-slot 'type))
2) (unless (subtypep slotd-type (slot-value super-slot 'type))
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2369L
1) \endscreen!
1) \endsubsubsection%{Example of Specializing compute-effective-slot-description}
1) \endSection%{The Slot Inheritance Protocol}
1) \beginSection{The Instance Structure Protocol}
**** File 2) MOPC.TEX[CLS,LSP]/1P/2564L
2)
2) \endscreen!
2) \endsubsubsection%{Example of Specializing compute-effective-slot-description}
2) \endSubSection%{The Slot Inheritance Protocol}
2) \endSection{Computing Inherited Information}
2) \beginSection{The Instance Structure Protocol}
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2383L
1) Level Instance Access. At the lower level, the user
1) has the ability to specify additional named storage to be allocated in an
1) instance. This Access-key level is also the focus of optimization
1) for slot access, and hence for additional storage specified by the user.
1) All the methods at the Slot Level can be defined in terms of functions at the
1) Access-key level.
1) \beginSubSection{Slot Level Instance Access}
**** File 2) MOPC.TEX[CLS,LSP]/1P/2580L
2) Level Instance Access. At the lower level, the user has the ability
2) to specify that additional named storage is to be allocated in an
2) instance. This access-key level is also the focus of optimization
2) for slot access, and hence for the additional storage specified by the user.
2) All the methods at the Slot Level can be defined in terms of functions at the
2) access-key level.
2) \beginSubSection{Slot Level Instance Access}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2416L
1) The generic function {\bf slot-value-using-class} is called by the
1) function {\bf slot-value}.
1) {\bf slot-value-using-class} returns the value of the slot with the
1) given name. All methods on slot-value-using-class call slot-missing if
1) the slot with the given name does not exist. Some methods on
1) slot-value-using-class may do additional checks, for example to see if
1) the slot is bound.
1) \Defmeth {slot-value-using-class} {(class standard-class) instance slot-name}
1) Returns the value of the slot named slot-name if such a slot
1) exists and is bound. If the slot does not exist calls slot-missing. If
1) the slot exists but is not bound calls slot-unbound.
1) \Defmeth {slot-value-using-class} {(class structure-class) instance slot-name}
1) Returns the value of the slot named slot-name if such a slot
1) exists. If the slot does not exists, it calls the generic function
1) slot-missing.
1) \endsubsubsection%{slot-value-using-class}
1) \beginsubsubsection{slot-boundp-using-class}
1) The generic function {\bf slot-boundp-using-class} is called by the
1) function {\bf slot-boundp}.
1) The generic function {\bf slot-boundp-using-class} tests whether a
1) specific slot in an instance of a given class is bound. Not all
1) metaclasses support this operation.
1) \Defmeth {slot-boundp-using-class} {(class standard-class) instance slot-name}
1) If a slot with the given name exists, and that slot is bound, returns
1) true. If a slot with the given name exists and that slot is not bound
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) returns false. If no slot with the given name exists the function
1) slot-missing is called.
1) \Defmeth {slot-boundp-using-class} {(class structure-class) instance slot-name}
1) If a slot with the given name exists, it returns true. If no slot with the
1) given name exists the function slot-missing is called.
1) \endsubsubsection%{slot-boundp-using-class}
1) \beginsubsubsection{slot-makunbound-using-class}
1) The generic function {\bf slot-makunbound-using-class}
1) is called by the function {\bf slot-makunbound}.
1) For metaclass which support unbound slots, the generic function {\bf
1) slot-makunbound-using-class} restores a slot to its unbound state.
1) Attempting to read a slot after it has been made unbound will result in
1) a call to {\bf slot-unbound}.
1) \Defmeth {slot-makunbound-using-class} {(class standard-class) instance slot-name}
1) If a slot with the given name exists in the class the slot is restored
1) to its original unbound state. If there is no slot with the given name
1) in the class calls slot-missing.
1) \Defmeth {slot-makunbound-using-class} {(class structure-class) instance slot-name}
1) Since this operation is not supported by structure-class, this method
1) signals an error.
1) \endsubsubsection%{slot-makunbound-using-class}
1) \beginsubsubsection{slot-exists-p-using-class}
1) The generic function {\bf slot-exists-p-using-class} is called by the
1) function {\bf slot-exists-p}.
1) The generic function {\bf slot-exists-p-using-class} tests whether a
1) slot by the given exists in the instance.
1) \Defmeth {slot-exists-p-using-class} {(class standard-class) instance slot-name}
1) If either a :instance or :class slot slot with the given name exists in
1) the class returns true. Otherwise returns false.
1) \Defmeth {slot-exists-p-using-class} {(class structure-class) instance slot-name}
1) If a slot with the given name exists in the class returns true.
1) Otherwise returns false.
1) \endsubsubsection{slot-exists-p-using-class}
1) \endSubSection%{Slot Level Instance Access}
1) \beginSubSection{Access-Key Instance Access}
1) At the Access-Key level, there is direct access to instances
1) of metatype standard-class. However, even at this level, instances
1) are accessed through a symbolic mapping. It is just that the set of
1) keys used for accessing the objects can be computed by a method on the
1) class. Optimized access through those keys is supported. Thus, a
1) user can think of a Loops class having a set of slots, and a set of
1) properties on those slots. At the lower level, the class might
1) generate a separate access key for a property list for each slot.
1) Note that even with this protocol, the user cannot portably change the
1) mechanisms for laying out storage, nor for class-of. There may be reasonable
1) semi-portable ways of doing these, but CLOS does not not specify
1) how to do this.
1) \beginsubsubsection{compute-class-access-keys}
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) The purpose of the generic function {\bf compute-class-access-keys}
1) is to compute the entire set of access keys that will be used with
1) an instance of standard-class. This generic function is called by the
1) update-dependent method on standard-class, and its value is cached
1) in an implementation dependent way with the class. The function
1) {\bf class-access-keys} can retrieve the latest value stored.
1) \Defmeth {compute-class-access-keys} {(class standard-class)}
1) This method returns two values, each of which must be a list of access-keys.
1) No access-key can appear more than once in a list, and the two lists may have
1) no elements in common. The first value is the set of access keys for which
**** File 2) MOPC.TEX[CLS,LSP]/1P/2613L
2) \Defgen {slot-value-using-class} {class instance slot-name}
2) The purpose of the generic function {\bf slot-value-using-class}
2) is to return the value of the slot with the name {\it slot-name}.
2) The generic function {\bf slot-value-using-class} is called by the
2) function {\bf slot-value}. {\bf slot-value} computes the class
2) of the instance as the first argument to {\bf slot-value-using-class}.
2) The behavior of {\bf slot-value-using-class} is undefined if {\it class}
2) is not the class of {\it instance}
2) \Defmeth {slot-value-using-class} {(class standard-class) instance slot-name}
2) Returns the value of the slot named slot-name if such a slot
2) exists and is bound. If the slot does not exist calls {\bf slot-missing}
2) with condition-code {\it slot-value}.
2) If the slot exists but is not bound calls {\bf slot-unbound}.
2) \endsubsubsection%{slot-value-using-class}
2) \beginsubsubsection{slot-value-using-class}
2) \Defgen {(setf slot-value-using-class)} {new-value class instance slot-name }
2) The purpose of the generic function {\bf (setf slot-value-using-class)}
2) is to set the value of the slot with the name {\it slot-name}.
2) This generic function is called by the
2) function {\bf (setf slot-value)} which computes the class
2) of the instance as the {\it class} argument to this function.
2) The behavior of {\bf (setf slot-value-using-class)} is undefined if {\it class}
2) is not the class of {\it instance}
2) \Defmeth {(setf slot-value-using-class)} {new-value (class standard-class) instance slot-name}
2) Sets the value of the slot named slot-name if such a slot
2) exists. If the slot does not exist calls {\bf slot-missing}
2) with condition-code {\it setf}.
2) \endsubsubsection%{(setf slot-value-using-class)}
2) \beginsubsubsection{slot-boundp-using-class}
2) \Defgen {slot-boundp-using-class} {class instance slot-name}
2) The purpose of the generic function {\bf slot-boundp-using-class}
2) is to test whether a slot {\it slot-name} in an instance of{\it class}
2) is bound. The generic function {\bf slot-boundp-using-class}
2) is called by the function {\bf slot-boundp}.
2) \Defmeth {slot-boundp-using-class} {(class standard-class) instance slot-name}
2) If a slot with the given name exists, and that slot is bound, returns
2) true. If a slot with name {\it slot-name} exists, but that slot is not bound
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) returns nil. If no slot with the given name exists, the function
2) slot-missing is called with condition argument slot-boundp.
2) \endsubsubsection%{slot-boundp-using-class}
2) \beginsubsubsection{slot-makunbound-using-class}
2) \Defgen {slot-makunbound-using-class} {class instance slot-name}
2) The purpose of the generic function {\bf slot-makunbound-using-class}
2) is to restore slot {\it slot-name} in instance to its unbound state.
2) For instances of standard-class, attempting to read a slot immediately
2) after it has been made unbound will result in
2) a call to {\bf slot-unbound}. {\bf slot-makunbound-using-class}
2) is called by the function {\bf slot-makunbound}.
2) \Defmeth {slot-makunbound-using-class} {(class standard-class) instance slot-name}
2) If a slot with the name {\it slot-name} exists in the class
2) the slot is restored to its original unbound state.
2) If there is no slot with the given name, a call is made to
2) slot-missing with condition code slot-makunbound.
2) \endsubsubsection%{slot-makunbound-using-class}
2) \beginsubsubsection{slot-exists-p-using-class}
2) \Defgen {slot-exists-p-class} {class instance slot-name}
2) The purpose of the generic function {\bf slot-exists-p-using-class}
2) is to test whether a slot {\it slot-name} will be accessible from this
2) instance. The generic function {\bf slot-exists-p-using-class}
2) is called by the function {\bf slot-exists-p}.
2) \Defmeth {slot-exists-p-using-class} {(class standard-class) instance slot-name}
2) If either an :instance or :class slot slot with the given name exists in
2) the class, this method returns that allocation. Otherwise returns nil.
2) \endsubsubsection%{slot-exists-p-using-class}
2) \beginsubsubsection{class-slot-value}
2) \Defgen {class-slot-value} {class slot-name}
2) The purpose of this generic function is to return the value of a
2) slot whose allocation is in the class {\it class}.
2)
2) \Defmeth {class-slot-value} {(class standard-class) slot-name}
2) This returns the value of the slot {\it slot-name} with allocation :class
2) in {\it class}. An error is signalled if there is no such slot.
2) \endsubsubsection%{class-slot-value}
2) \endSubSection%{Slot Level Instance Access}
2) \beginSubSection{Access-Key Instance Access}
2) At the access-Key level, there is direct access to instances
2) of metatype standard-class. However, even at this level, instances
2) are accessed through a symbolic mapping. The set of
2) keys used for accessing the objects is computed by a method on the
2) class. Optimized access through those keys is supported.
2) Note that the user cannot portably change the mechanisms for laying out
2) storage, nor for augmenting class-of.
2) \beginsubsubsection{compute-class-access-keys}
2) \Defgen {compute-class-access-keys} {class}
2) The purpose of the generic function {\bf compute-class-access-keys}
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) is to compute the entire set of access keys that will be used with
2) instances of a standard-class. This generic function is called by the
2) update-dependent method on standard-class, and its values stored as the
2) value of the reader {\bf class-access-keys}.
2) \Defmeth {compute-class-access-keys} {(class standard-class)}
2) This method returns two values, each of which must be a list of access-keys.
2) No access-key can appear more than once in a list, and the two lists may have
2) no elements in common. The first value is the set of access keys for which
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2555L
1) The storage that is allocated for any instance is determined by
1) a set of access keys computed by compute-class-access-keys.
1) The latest values stored away by update-dependent can be obtained by
1) this function.
1) Returns two values, a list of instance-keys and a list of class-keys.
1) The first will be accessible by standard-instance-access,
1) and the second through standard-class-access.
1)
1)
**** File 2) MOPC.TEX[CLS,LSP]/1P/2768L
2) \Defun {class-access-keys} {standard-class}
2) {\bf class-access-keys} is a function that takes an instance of
2) standard-class as an argument. It returns the latest values stored
2) by update-dependent. It returns two values, a list of instance-keys and a list of class-keys.
2) The first set of keys will be accessible by standard-instance-access,
2) and the second through standard-class-access.
2)
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2572L
1) Allocate-standard-instance is a function that takes an instance of
1) standard-class as an argument. It uses information cached in the class
1) by update-dependent to create a structure that has enough room
1) for one entry for each access-key on the list of instanceaccess keys.
1) (defun allocate-standard-instance (class)
1) ;; implementation dependent code for allocation
1) )
1)
1) \endsubsubsection%{allocate-standard-instance}
1) \beginsubsubsection{standard-instance-access}
1) The function {\bf standard-instance-access} is the low level access
1) primitive for instances in CLOS.
1) \screen!
1) (defun standard-instance-access (instance access-key)
1) ;;instance must be of metatype standard-instance
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) ;;return value from instance, and condition-code
1) )
1) \endscreen!
1) The first value returned by standard-instance-access is the value in
1) storage if there is one. The second value is a condition-code, one of
1) :value, :unbound, :missing.
1) Thus, some model code for slot-value-using-class for standard-class is:
1) \screen!
1) (defmethod slot-value-using-class ((class standard-class) object slot-name)
1) (multiple-value-bind (value condition)
1) (standard-instance-access object slot-name)
1) (ecase condition
1) (:value value)
1) (:missing (slot-missing class object slot-name 'slot-value))
1) (:unbound (slot-unbound class object slot-name))))
1) \endscreen!
1) The code for the other slot level methods for standard-class are coded
1) similarly.
1) \endSubSection%{Access-Key Instance Access}
1) \beginSubSection{Optimized Symbolic Level Instance Access}
1) The standard-instance-access function provides the basic interface to
1) the implementation-specific standard instance access optimization.
1) In order to support the optimization there is a contract between
1) standard-instance-access and the kernel methods which provide the class
1) updating protocol. Specifically, standard-instance-access is allowed to
1) assume that the set of access-keys does not change unless update-dependent
1) has been called, and it is the responsibility of update-dependent
1) to inform each of the effected methods about how to update themselves.
1) In order to allow flexible use of the optimization
1) standard-instance-access provides, there is a mechanism for deoptimizing
1) calls to standard-instance-access for a particular class. This
1) mechanism causes all the calls to standard-instance-access for a
1) particular class to call the trap function instead. The trap function
1) received the instance and the description as its arguments.
1) \Defun {deoptimize-standard-instance-access} {class}
1) ...
1) \endSubSection%{Optimized Symbolic Level Instance Access}
1) \endSection%{The Instance Structure Protocol}
1) \beginSection{The Instance Access Optimization Protocol}
1) As described in chapters 1 and 2, most code access instances at the slot
1) level. But, as described in the Instance Structure Protocol section,
1) a call to slot-value results in a call to the slot-value-using-class
1) generic function which then calls standard-instance-access. If every
1) call to slot-value had to do this generic function call, slot access
1) would be too slow.
1) To solve this problem, CLOS provides a mechanism for optimizing calls to
1) slot-value. At compile-time, this mechanism optimizes calls to
1) slot-value where it is possible to convert the call to a use of
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) standard-instance-access. This requires that the compiler be able to
1) ascertain the class of an instance (it can be a subclass of that class
1) at run-time).
1) This mechanism is general enough that it can be used to optimize any
1) access to instances whose class is known at compile time.
1) {\it
1) There is a notion which needs to be defined here in a protable way.
1) It is the concept of a context in which a call to standard-instance-access
1) can be optimized.
1) }
1) The fundamental hook for this mechanism is the optimize-instance-access
1) generic function. This generic function is called on any instance
1) accessing form which, if it were converted to a call to
1) standard-instance-access could be further optimized. This gives the
1) metaclass programmer an opportunity to optimize any instance accessing
1) form into a call to standard-instance-access whenever it would do any
1) good.
1) optimize-instance-access receives as arguments the class of the instance
1) being accessed (or a superclass) the function being called on the
1) instance, all the arguments to the function, the particular one of those
1) arguments which will be the instance at run-time and information about
1) the context the access is in. The context will be the symbol :effect if
1) the compiler is guaranteeing that this access is for effect only.
1) When a metaclass optimizes slot accesses, it may do so in a way that
**** File 2) MOPC.TEX[CLS,LSP]/1P/2782L
2) \Defun {allocate-standard-instance} {standard-class}
2) Allocate-standard-instance is a function that takes an instance of
2) standard-class as an argument. It uses information collected in the class
2) by update-dependent to create a structure that has enough room
2) for one entry for each access-key on the list of instance access-keys.
2) \Defun {allocate-standard-instance} {standard-class}
2) \endsubsubsection%{allocate-standard-instance}
2) \beginsubsubsection{standard-instance-access}
2) \Defun {standard-instance-access} {standard-instance access-key}
2) The function {\bf standard-instance-access} is the low level access
2) primitive for instances of standard-class in CLOS. It does its access
2) based on the set of values stored for class-access-keys.
2) If the access-key is missing it calls standard-instance-missing with the class
2) the instance and the key. The standard method on
2) standard-instance-missing calls slot-missing.
2) If the key is unbound it calls standard-instance-unbound with the class
2) the instance and the key The standard-method on
2) standard-instance-unbound calls slot-unbound.
2) If the key exists and is bound it just returns the value.
2) {\it Unfortunately all we have for this is model code, no writeup yet.}
2) Some model code follows:
2) \screen!
2) (defun standard-instance-access (instance key)
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) (let ((class (class-of instance)))
2) (multiple-value-bind (instance-keys class-keys)
2) (class-access-keys class)
2) (cond ((member key instance-keys)
2) (if (internal-instance-boundp instance key)
2) (internal-instance-value instance key)
2) (standard-instance-unbound class instance key)))
2) ((member key class-keys)
2) (if (internal-class-boundp instance key)
2) (internal-class-value instance key)
2) (standard-instance-unbound class instance key)))
2) (t
2) (standard-instance-missing class instance key))))))
2) \endscreen!
2) \endsubsubsection%{standard-instance-access}
2) \beginsubsubsection{standard-class-access}
2) \screen!
2) (defun standard-class-access (instance key)
2) (let ((class (class-of instance)))
2) (multiple-value-bind (ignore class-keys)
2) (class-access-keys class)
2) (if (member key class-keys)
2) (internal-class-value instance key) ; class slots are always bound
2) (standard-instance-missing class instance key)))))
2) \endscreen!
2) \endsubsubsection%{standard-class-access}
2) \beginsubsubsection{standard-instance-missing}
2) \screen!
2) (defmethod standard-instance-missing ((class standard-class) instance key)
2) (slot-missing class instance key))
2) \endscreen!
2) \endsubsubsection%{standard-instance-missing}
2) \beginsubsubsection{standard-instance-unbound}
2) \screen!
2) (defmethod standard-instance-unbound ((class standard-class) instance key)
2) (slot-unbound class instance key))
2) \endscreen!
2) \endsubsubsection%{standard-instance-unbound}
2) \beginsubsubsection{standard-instance-boundp}
2) \screen!
2) (defun standard-instance-boundp (instance key)
2) (let ((class (class-of instance)))
2) (multiple-value-bind (instance-key class-keys)
2) (class-access-keys class)
2) (cond ((member key instance-keys)
2) (internal-instance-boundp instance key))
2) ((member key class-keys)
2) (internal-instance-boundp instance key))
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) (t
2) (standard-instance-missing class instance key))))))
2) \endscreen!
2) \endsubsubsection%{standard-instance-boundp}
2) \beginsubsubsection{standard-instance-makunbound}
2) The purpose of this function is make the specified by access-key
2) be unbound.
2) \endsubsubsection%{standard-instance-makunbound}
2) \endSubSection%{Access-Key Instance Access}
2) \beginSubSection{The Instance Access Optimization Protocol}
2) As described in chapters 1 and 2, most code access instances at the slot
2) level. But, as described above, a call to slot-value results in a call
2) to the slot-value-using-class generic function which then calls
2) standard-instance-access. If every call to slot-value had to go through
2) this generic function call, to get to the call to
2) standard-instance-access slot access would be unbearably slow.
2) To solve this problem, CLOS provides a mechanism for optimizing calls to
2) slot-value and other instance access functions. At compile-time, this
2) mechanism optimizes calls to slot-value where it is possible to convert
2) the call to a use of standard-instance-access. This requires that the
2) compiler be able to ascertain the class of the relevant arguments to the
2) instance access function (it can be a subclass of that class at
2) run-time).
2) This mechanism is general enough that it can be used to optimize any
2) access to instances whose class is known at compile time.
2) The fundamental hook for this mechanism is the
2) define-instance-access-optimzation macro. This macro tells the compiler
2) that a given function ends up calling standard-instance-access and so
2) calls to it might be optimizable.
2) The general idea here is that this is a compiler optimizer interface.
2) You declare to the compiler the function that needs to be optimized, its
2) argument list, and for which of those arguments the class must be known.
2) Then, in contexts where the class of that argument is known, the
2) compiler calls the declared optimization function. The first argument
2) will be the known class, the second argument will be the actual form.
2) The optimization function should return the form which should be used.
2) The returned form usually is a call to standard-instance-access.
2) \screen!
2) ;;;
2) ;;; The CLOS system includes these calls to
2) ;;; define-instance-access-optimization which arrange
2) ;;; for calls to slot-value and (setf slot-value) to
2) ;;; go through the appropriate optimization mechanism.
2) ;;;
2) (define-instance-access-optimization slot-value
2) (instance slot-name)
2) instance
2) optimize-slot-value)
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) (define-instance-access-optimization (setf slot-value)
2) (new-value instance slot-name)
2) instance
2) optimize-setf-slot-value)
2) \endscreen!
2) When a metaclass optimizes slot accesses, it may do so in a way that
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2692L
1) \Defmeth {can-deoptimize-slot-accesses-p} {(class standard-class)}
1) Returns true.
1) \Defmeth {can-deoptimize-slot-accesses-p} {(class structure-class)}
1) Returns false.
1) \Defmeth {deoptimize-slot-accesses} {(class standard-class)}
1) Deoptimizes its optimized slot accesses by calling
1) deoptimize-standard-instance-access.
1) \Defmeth {can-deoptimize-slot-accesses-p} {(class structure-class)}
1) Signals an error.
1) \endSection%{The Instance Access Optimization Protocol}
1) \beginSection{The Method Lookup Protocol}
**** File 2) MOPC.TEX[CLS,LSP]/1P/2953L
2) \beginsubsubsection{optimizing slot-value}
2) \Defmeth {optimize-slot-value} {(class standard-class) form}
2) This method translates the call to slot-value into a call to
2) standard-instance-access with the access key being the slot-name.
2) \Defmeth {optimize-setf-slot-value} {(class standard-class) form}
2) This method translates the call to (setf slot-value) into a call to
2) (setf standard-instance-access) with the access key being the slot-name.
2) \endsubsubsection%{optimizing slot-value}
2) \endSubSection%{The Instance Access Optimization Protocol}
2) \beginSubSection{Deoptimizing Instance Access}
2) The standard-instance-access function provides the basic interface to
2) the implementation-specific standard instance access optimization.
2) In order to support the optimization there is a contract between
2) standard-instance-access and the kernel methods which provide the class
2) updating protocol. Specifically, standard-instance-access is allowed to
2) assume that the set of access-keys does not change unless update-dependent
2) has been called, and it is the responsibility of update-dependent
2) to inform each of the effected methods about how to update themselves.
2) In order to allow flexible use of the optimization
2) standard-instance-access provides, there is a mechanism for deoptimizing
2) calls to standard-instance-access for a particular class.
2) \beginsubsubsection{can-deoptimize-slot-accesses-p}
2) \screen!
2) (defmethod can-deoptimize-slot-accesses-p ((class standard-class))
2) 't)
2) \endscreen!
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) \endsubsubsection%{can-deoptimize-slot-accesses-p}
2) \beginsubsubsection{deoptimize-slot-accesses}
2) \Defmeth {deoptimize-slot-accesses} {(class standard-class)}
2) Deoptimizes its optimized slot accesses by calling
2) deoptimize-standard-instance-access, with the class as the first
2) argument, a second argument of \#'slot-value-using-class and third
2) argument of \#'(setf slot-value-using-class). This causes the
2) deoptimized slot accesses to go through the complete
2) slot-value-using-class protocol.
2) \endsubsubsection%{deoptimize-slot-accesses}
2) \beginsubsubsection{deoptimize-standard-instance-access}
2) \Defun {deoptimize-standard-instance-access} {class read-trap write-trap}
2) This function causes all the calls to standard-instance-access for a
2) particular class to call the trap functions instead. The trap function
2) received the class of the intance, the instance and the access-key as
2) arguments.
2) \screen!
2) (defun deoptimize-standard-instance-accesses (class read-trap write-trap)
2) ;; Cause all optimized accesses to instances of class to go
2) ;; through one of the trap functions instead. Reads will go
2) ;; through the read-trap function, writes will go through the
2) ;; write trap function. The reap trap function will be called
2) ;; with three arguments, the class, the instance and the key.
2) ;; The write trap function will be called with 4 arguments,
2) ;; the new value, the class, the instance and the key.
2) )
2) \endscreen!
2) \endsubsubsection%{deoptimize-standard-instance-access}
2) \endSubSection%{Deoptimizing Instance Access}
2) \endSection%{The Instance Access Protocol}
2) \beginSection{The Method Lookup Protocol}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2722L
1) When the effective method has been determined, it is converted to
**** File 2) MOPC.TEX[CLS,LSP]/1P/3049L
2) The specification for the precise way the kernel computes the effective
2) method appears in chapter 1. This section describes the protocol used
2) to compute and invoke the effective method.
2) When the effective method has been determined, it is converted to
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2727L
1) The specification for the precise way the kernel computes the effective
1) method appears in chapter 1. This section describes the protocol used
1) to compute and invoke the effective method.
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
1) The key component in this protocol is the discriminator code for the
1) generic function. The discriminator code for a generic function is
1) called whenever the generic function is called; it computes the
1) effective method and invokes it. The discriminator code for a generic
1) function is computed each time the generic function changes. When the
1) generic function itself is called, the pre-computed discriminator code
1) is called. The protocol described here is used to compute the
1) discriminator code, thus the protocol described here is not invoked when
1) the generic function is called, it is invoked whenever the generic
1) function is updated. This allows method lookup to be a fast operation.
1) The standard-method on update-generic-function calls
1) compute-discriminator-code whenever the generic function changes.
1) compute-discriminator-code is expected to return the discriminator code
1) for the generic function. This discriminator code must be valid until
1) the next time update-generic-function is called.
1) The standard-method on compute-discriminator-code provides the
1) documented behavior of computing the effective method and calling it.
1) It does this by providing a second layer of protocol, specifically the
1) compute-effective-method generic function. compute-effective-method is
1) called by the standard-method on compute-discriminator-code to compute
1) the effective method for a set of applicable methods.
1) There are also several support functions supplied by the kernel to
1) assist users in extending the method lookup protocol. These support
**** File 2) MOPC.TEX[CLS,LSP]/1P/3058L
2) The central component of the method lookup protocol is a piece of code
2) called the discriminator code for the generic function. The
2) discriminator code for a generic function is called when the generic
2) function is called. The discriminator code must determine the effective
2) method to be called and apply it to the arguments the generic function
2) received.
2) The discriminator code is not computed at generic function invocation
2) time, it is computed and stored whenever the generic function changes or
2) whenever the class lattice changes in a way that affects the effective
2) methods of the generic function. The entry to this protocol is the
2) generic function {\bf compute-discriminator-code}.
2) The standard-method on compute-discriminator-code uses the generic
2) function {\bf compute-effective-method} to construct an effective method
2) from a set of applicable methods. {\bf compute-discriminator-code}
2) constructs code that selects from the set of effective methods to be
2) called at run time.
2) In this protocol, there are several support functions supplied to
2) assist users in extending the method lookup protocol. These support
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2761L
1) \Defgen {compute-discriminator-code} {generic-function}
**** File 2) MOPC.TEX[CLS,LSP]/1P/3082L
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) \beginsubsubsection{compute-discriminator-code}
2) \Defgen {compute-discriminator-code} {generic-function}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2788L
1) \Defgen {compute-effective-method} {generic-function applicable-methods
1) method-combination-type method-combination-arguments}
1) \Defmeth {compute-effective-method} {(generic-function standard-generic-function) applicable-methods method-combination-type method-combination-arguments}
1) {\it Actually, there is one method here for each pre-defined
1) method-combination-type. This needs to be explained in terms how
1) define-method-combination expands into a defmethod for
1) compute-effective-method.
1) }
1) \beginSubSection{Support Functions for Method Lookup}
1) In order to help the user use the method lookup protocol the CLOS kernel
1) provides some helpful support functions.
1) \Defun {compute-applicable-methods} {generic-function arguments}
1) Given a generic function and a set of arguments, this uses the standard
1) rules to determine the ordered set of applicable methods.
1) \Defun {compute-combination-points} {generic-function}
1) Computes all the combination points for this generic functions. That is
1) all the points at which (if you are using combined-methods) methods must
1) be combined. For each point it also provides the ordered set of
1) methods applicable at the point.
1) {\it This may sound like it is too implementation specific to be useful
1) in the metaobject protocol, but I think that is because of the way I am
1) describing it. I believe a lot of method lookup hackers are going to
1) want to compute this, and given that it is hard to compute accurately
1) and quickly I think we should provide it.
1) }
1) \Defun {check-keyword-arguments} {generic-function lambda-list methods args}
**** File 2) MOPC.TEX[CLS,LSP]/1P/3111L
2) \endsubsubsection%{compute-discriminator-code}
2) \beginsubsubsection{compute-effective-method}
2) \Defgen {compute-effective-method} {generic-function
2) method-combination applicable-methods}
2) \Defmeth {compute-effective-method} {(generic-function standard-generic-function) (method-combination standard-method-combination) applicable-methods}
2) This method supports the construction of an effective method of the
2) kind described as the standard-method-combination in Chapter 1.
2) In addition to this method, there is one method here for each pre-defined
2) method-combination-type. See the explanation for method-combination objects
2) of how define-method-combination expands into a defmethod for
2) compute-effective-method. We must also specify here which ones are specified
2) for CLOS. The examples given in expansion of define-method-combination
2) are illustrative.
2) \endsubsubsection%{compute-effective-method}
2) \beginsubsubsection{compute-applicable-methods}
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) \Defun {compute-applicable-methods} {generic-function arguments}
2) Given a generic function and a set of arguments, this uses the standard
2) rules to determine the ordered set of applicable methods.
2) \endsubsubsection%{compute-applicable-methods}
2) \beginsubsubsection{check-keyword-arguments}
2) \Defun {check-keyword-arguments} {generic-function lambda-list methods args}
***************
**** File 1) NEWMOP.TEX[CLS,LSP]/1P/2827L
1) signals an error.
1) \Defun {make-method-call} {method-list \key operator identity-with-one-argument}
1) This is documented in chapter 2.
1) \Defun {make-function-call} {function}
1) This has behavior similar to make-method-call. It produces a call to
1) the function with all the arguments of the generic function.
1) {\it we should invent a better name for this. }
1) \Defun {make-effective-method-function} {generic-function effective-method-body}
1) This takes the effective method body as computed by
1) compute-effective-method-body and converts it to a function which
1) implements the effective method. This function accepts the same
1) arguments the generic function accepts. This function does the standard
1) keyword congruence checking. This function arranges to call all the
1) methods ``as if with :allow-other-keys t''.
1) {\it Basically, make-effective-method-function, make-method-call and
1) make-function-call are the ones that have the contract that makes
1) calling methods work. They communicate the information about what
1) parameters the arguments will be bound to, how to hack :allow-other-keys
1) t etc. }
1) {\it I am concerned that actually we have to get rid of make-method-call
1) and have a call-method special form. Otherwise, I don't know how
1) someone is going to build a portable stepper for standard generic
1) functions.
1) }
1) \endSubSection%{Support Functions for Method Lookup}
1) \beginSubSection{Example of using the Method Lookup Protocol}
**** File 2) MOPC.TEX[CLS,LSP]/1P/3146L
2) signals an error.
2)
2) \endsubsubsection%{check-keyword-arguments}
2) \beginsubsubsection{make-method-call}
2) \Defun {make-method-call} {method-list \key operator identity-with-one-argument}
2) This is documented in chapter 2.
2) {\it There is a problem with the method combination mechanism specified
2) in chapter 2 which is that it doesn't allow the combined method to
2) change the arguments that are passed to the individual methods. We
2) should re-address the issues associated with the combined-method
2) arguments abstraction. }
1) NEWMOP.TEX[CLS,LSP] and 2) MOPC.TEX[CLS,LSP] 3-13-88 22:42 pages 1,1
2) \endsubsubsection%{make-method-call}
2) \beginSubSection{Example of using the Method Lookup Protocol}
***************